package com.wyy.todo.resolver;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wyy.todo.beans.Schedules;
import com.wyy.todo.beans.SchedulesInput;
import com.wyy.todo.beans.SchedulesVo;
import com.wyy.todo.graphqlerror.DataFetchingException;
import com.wyy.todo.dao.SchedulesInputDao;
import graphql.kickstart.tools.GraphQLMutationResolver;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static com.wyy.todo.constants.SchedulesConstants.*;

@Service
public class SchedulesMutationResolver implements GraphQLMutationResolver {

    @Autowired
    private SchedulesInputDao schedulesInputDao;

    public Integer addToDo(SchedulesInput schedulesInput){
        // 检查传参
        checkParamIsEmpty(schedulesInput);
        // 判断是否重复
        checkDataIsRepeat(schedulesInput.getData());
        // 构建
        Schedules schedules = assembleAddSchedules(schedulesInput.getData());
        // 查询
        return schedulesInputDao.insert(schedules);
    }


    public SchedulesVo updateToDo(SchedulesInput schedulesInput) {
        // 检查参数
        checkParamIsEmpty(schedulesInput);
        // 判断要修改的值是否重复
        checkDataIsRepeat(schedulesInput.getData());
        // 构建 Schedules
        Schedules schedules = getSchedulesOne(schedulesInput.getId());
        // 修改数据
        schedules.setData(schedulesInput.getData());
        // 修改
        updateSchedules(schedules);
        // 返回
        return getSchedulesVo(schedules);
    }


    public Integer deleteAllCompletedToDoByStatus() {
        // 设置条件
        QueryWrapper<Schedules> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SCHEDULES_STATUS, SCHEDULES_STATUS_VAL_COMPLETED);
        // 执行删除
        return schedulesInputDao.delete(queryWrapper);
    }

    public SchedulesVo updateToDoStatusById(Long id) {
        // 根据 id 查询 schedules
        Schedules schedules = getSchedulesOne(id);
        // 切换 status
        schedules.setStatus(schedules.getStatus() == 1 ? SCHEDULES_STATUS_VAL_COMPLETED: SCHEDULES_STATUS_VAL_ACTIVE);
        // 修改
        updateSchedules(schedules);
        // 返回
        return getSchedulesVo(schedules);
    }

    public Integer deleteOneToDoById(Long id) {
        return schedulesInputDao.deleteById(id);
    }


    private Schedules getSchedulesOne(Long id) {
        Schedules schedules = schedulesInputDao.selectById(id);
        if (ObjectUtils.isEmpty(schedules)) {
            throw new DataFetchingException(DataFetchingException.Type.NOT_FOUND);
        }
        return schedules;
    }


    private void updateSchedules(Schedules schedules) {
        int aff = schedulesInputDao.updateById(schedules);
        if (aff == 0) {
            throw new DataFetchingException(DataFetchingException.Type.UPDATE_FAIL);
        }
    }


    private Schedules assembleAddSchedules(String data) {
        return Schedules.builder()
                .data(data)
                .status(SCHEDULES_STATUS_VAL_ACTIVE)
                .build();
    }

    private void checkDataIsRepeat(String data) {
        QueryWrapper<Schedules> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(true, SCHEDULES_DATA, data);
        Schedules temp = schedulesInputDao.selectOne(queryWrapper);
        if (ObjectUtils.isNotEmpty(temp)) {
            throw new DataFetchingException(DataFetchingException.Type.EXPIRED);
        }
    }


    private void checkParamIsEmpty(SchedulesInput schedulesInput) {
        if (ObjectUtils.isEmpty(schedulesInput.getData()) || "".equals(schedulesInput.getData())) {
            throw new DataFetchingException(DataFetchingException.Type.PARAM_ISEMPTY);
        }
    }


    private Schedules assembleUpdateSchedules(SchedulesInput schedulesInput) {
        return Schedules.builder()
                .id(schedulesInput.getId())
                .data(schedulesInput.getData())
                .status(schedulesInput.getStatus())
                .build();
    }


    private SchedulesVo getSchedulesVo(Schedules schedules) {
        return SchedulesVo.builder()
                .id(schedules.getId())
                .data(schedules.getData())
                .status(schedules.getStatus())
                .build();
    }

}
